/**
 * 云静表单
 */
layui.use(['jquery', 'yunj', 'element', 'elemProgress', 'button', 'dropdown', 'validate'], function () {
    let win = window;
    let doc = document;
    let $ = layui.jquery;
    let element = layui.element;
    let elemProgress = layui.elemProgress;
    let button = layui.button;
    let dropdown = layui.dropdown;
    let validate = layui.validate;

    class YunjForm {

        constructor(obj) {
            this.id = obj.id;                       // 当前对象id

            this.rawEl = obj.elem;                  // 原始元素

            this.rawArgs = obj.args;                // 原始数据

            this.boxEl = null;                      // 顶部父元素

            this.headerBoxEl = null;                // 表单header元素

            this.tabBoxEl = null;                   // 表单选项卡父元素

            this.url = null;                        // 请求地址

            this.urlParam = null;                   // url参数

            this.isPopup = false;                   // 是否弹出层

            this.rawPageWin = null;                 // 来源页面window对象

            this.rawTable = null;                   // 来源表格

            this.tabTitleEl = null;                 // 当前tab标题元素

            this.tab = null;                        // 当前tab

            this.tabContentEl = null;               // 当前tab内容元素

            this.vals = {};                          // 表单字段值

            this.fields = {};                        // 表单字段实例容器

            this.elemProgress = null;               // 表单加载进度对象

            this.init();
        }

        init() {
            let that = this;
            if (!that.id || !that.rawArgs || win.yunj.isEmptyObj(that.rawArgs)) return false;
            // 初始化布局
            that.initLayout();
            // 设置数据
            that.setData();
            // 进度0
            that.elemProgress = elemProgress({elem: that.boxEl.hasClass('head-fixed') ? that.boxEl.find('.progress') : that.boxEl});
            // 渲染
            that.render().then(res => {
                // 设置事件绑定
                that.setEventBind();
                // 进度100%
                that.elemProgress.reset_progress(100);
            });
        }

        // 初始化布局
        initLayout() {
            let that = this;
            let headFixed = false;
            // TODO 头部固定站暂时移除
            // let iframeChildren = $(".yunj-iframe-content").children();
            // if (iframeChildren.length === 1 && iframeChildren.eq(0).attr("type") === "yunj" && iframeChildren.eq(0).attr("id") === that.id)
            //     headFixed = true;
            let layout = `<div class="yunj-form-box ${headFixed ? 'head-fixed' : ''}" lay-filter="${that.id}" >
                            ${headFixed ? '<div class="progress"></div>' : ''}
                            <div class="yunj-form-header">
                                <div class="partition"></div>
                                <div class="content">
                                    <h2></h2>
                                    <div class="btn-box"></div>
                                </div>
                            </div>
                            <div class="layui-tab" lay-filter="${that.id}_tab"></div>
                        </div>`;
            that.rawEl.after(layout);
        }

        // 设置数据
        setData() {
            let that = this;
            let id = that.id;
            let rawArgs = that.rawArgs;
            that.boxEl = $(`.yunj-form-box[lay-filter=${id}]`);
            that.headerBoxEl = that.boxEl.find(`.yunj-form-header`);
            that.tabBoxEl = that.boxEl.find(`.layui-tab[lay-filter=${id}_tab]`);

            that.url = rawArgs.hasOwnProperty('url') ? rawArgs.url : yunj.url(false);
            that.urlParam = yunj.urlParam(null, {});
            that.isPopup = that.urlParam.hasOwnProperty('isPopup') && that.urlParam.isPopup === 'yes';

            that.rawPageWin = yunj.rawPageWin();
            if (that.rawPageWin && that.urlParam.hasOwnProperty('rawTable'))
                that.rawTable = that.rawPageWin.yunj.table[that.urlParam.rawTable];
        }

        // 渲染
        async render() {
            let that = this;
            that.renderTitle();
            that.renderTab();
            await that.renderFields();
            that.renderButton();
            // 表单渲染完成事件触发
            $(doc).trigger(`yunj_form_${that.id}_render_done`);
            return 'done';
        }

        // 渲染标题
        renderTitle() {
            let that = this;
            let title = yunj.currPageTitle(that.isPopup);
            if (title.length > 0) that.headerBoxEl.find('.content h2').html(title);
        }

        // 判断是否设置tab
        isSetTab() {
            return this.rawArgs.hasOwnProperty("tab");
        }

        // 渲染表单选项卡
        renderTab() {
            let that = this;
            if (that.tabBoxEl.find('.layui-tab-content').length > 0) return;
            let titleHtml = '';
            let contentHtml = '';
            if (!that.isSetTab()) {
                contentHtml += `<div class="layui-tab-item layui-show">
                                    <form class="layui-form layui-form-pane yunj-form" lay-filter="${that.id}_form"></form>
                                </div>`;
            } else {
                let tabs = that.rawArgs.tab;
                let i = 0;
                for (let tab in tabs) {
                    if (!tabs.hasOwnProperty(tab)) continue;
                    titleHtml += `<li class="${i === 0 ? 'layui-this' : ''}" data-tab="${tab}">${tabs[tab]}</li>`;
                    contentHtml += `<div class="layui-tab-item ${i === 0 ? 'layui-show' : ''}">
                                    <form class="layui-form layui-form-pane yunj-form" lay-filter="${that.id}_form${tab ? `_${tab}` : ""}"></form>
                                </div>`;
                    i++;
                }
            }
            if (titleHtml) titleHtml = `<ul class="layui-tab-title">${titleHtml}</ul>`;
            if (contentHtml) contentHtml = `<div class="layui-tab-content">${contentHtml}</div>`;
            let tabHtml = titleHtml + contentHtml;
            that.tabBoxEl.html(tabHtml);
            that.setTabData();
        }

        // 设置表单选项卡值
        setTabData() {
            let that = this;
            let tabTitleEl = null;
            let tab = null;
            if (that.isSetTab()) {
                tabTitleEl = that.tabBoxEl.find(`.layui-tab-title li.layui-this`);
                tab = tabTitleEl.data("tab");
            }
            that.tabTitleEl = tabTitleEl;
            that.tab = tab;
            that.tabContentEl = that.tabBoxEl.find(`.layui-tab-content .layui-tab-item.layui-show`);
        }

        // 渲染字段
        async renderFields() {
            let that = this;
            console.log(that.rawArgs.hasOwnProperty("field"));
            if (!that.rawArgs.hasOwnProperty("field")) return 'done';
            await that.setFormVals();
            console.log(that.vals);
            await that.renderFieldsHandle();
            that.setFieldsLabelLayout();
            return 'done';
        }

        // 设置表单字段值
        setFormVals() {
            let that = this;
            return new Promise(resolve => {
                if (!that.rawArgs.load) {
                    that.vals = {};
                    resolve('done');
                    return;
                }
                yunj.request(that.url, {builderId: that.id, builderAsyncType: 'load'}, "post").then(res => {
                    that.vals = res.data;
                    resolve('done');
                }).catch(e => {
                    yunj.error("表单字段值查询失败");
                });
            });
        }

        // 渲染字段处理
        async renderFieldsHandle() {
            let that = this;
            let vals = that.vals;
            if (that.isSetTab()) {
                for (let tab in that.rawArgs.tab) {
                    if (!that.rawArgs.tab.hasOwnProperty(tab)) continue;
                    await that.renderFieldsLayout(that.rawArgs.field[tab], vals, tab);
                }
            } else {
                await that.renderFieldsLayout(that.rawArgs.field[tab], vals);
            }
            return 'done';
        }

        async renderFieldsLayout(fields, vals, tab = "") {
            let that = this;
            for (let key in fields) {
                if (!fields.hasOwnProperty(key)) continue;
                let args = fields[key];
                // args.value
                if (yunj.isObj(vals) && vals.hasOwnProperty(key)) {
                    args.value = vals[key];
                    delete vals[key];
                }

                await new Promise(resolve => {
                    yunj.formField(args.type, {
                        formId: that.id,
                        tab: tab,
                        key: key,
                        args: args,
                    }).then(field => {
                        return field.render(`.layui-tab[lay-filter=${that.id}_tab] .layui-tab-content .yunj-form[lay-filter=${that.id}_form${tab?`_${tab}`:""}]`);
                    }).then(field => {
                        that.fields[field.id] = field;
                        resolve(`${key} done`);
                    }).catch(err => {
                        console.log(err);
                        resolve(`${key} done`);
                    });
                });
            }
        }

        // 设置表单字段label布局
        setFieldsLabelLayout() {
            let that = this;
            let labelMaxWidth = 0;
            let formItemEl = that.tabContentEl.find('.yunj-form-item:not(.layui-form-textarea):not(.yunj-form-editor):not(.yunj-form-markdown):not(.yunj-form-imgs)');
            formItemEl.each(function () {
                let currLabelWidth = $(this).find('.layui-form-label').outerWidth();
                if (currLabelWidth > labelMaxWidth) labelMaxWidth = currLabelWidth;
            });
            let inc = 1;
            formItemEl.find('.layui-form-label').css('width', labelMaxWidth + inc + 'px');
        }

        // 渲染按钮
        renderButton() {
            let that = this;

            if (!that.rawArgs.hasOwnProperty('button')) return;
            let btnBoxEl = that.headerBoxEl.find('.btn-box');
            let btnBoxHtml = btnBoxEl.html();
            let outbtnArr = [];
            let currWidth = $(doc).width();
            if (currWidth < 375) {
                outbtnArr = ['submit'];
            } else if (currWidth >= 375 && currWidth <= 480) {
                outbtnArr = ['back', 'submit', 'reset'];
            }
            let outbtnArrLen = outbtnArr.length;
            if (outbtnArrLen <= 0 && btnBoxHtml.length > 0) return;

            btnBoxEl.html('');
            let ddHtml = '';
            let btnArr = that.rawArgs.button;
            for (let i in btnArr) {
                if (!btnArr.hasOwnProperty(i)) continue;
                let type = btnArr[i];
                if (!button.hasOwnProperty(type)) continue;
                if (outbtnArrLen <= 0 || outbtnArr.indexOf(type) !== -1) {
                    button[type](that.id).render(`.yunj-form-box[lay-filter=${that.id}] .yunj-form-header .btn-box`);
                } else {
                    ddHtml += button[type](that.id).layout(true);
                }
            }
            if (ddHtml.length > 0) {
                let dropdownLayout = dropdown.layout(ddHtml);
                btnBoxEl.append(dropdownLayout);
            }
            return true;
        }

        // 切换选项卡
        tabChange() {
            let that = this;
            that.setTabData();
            that.setFieldsLabelLayout();
            that.setFieldsMarkdownEditormdReload();
        }

        // 设置字段 type=markdown mode=editormd 的字段重新加载
        setFieldsMarkdownEditormdReload() {
            let that = this;
            let fields = that.rawArgs.field[that.tab];
            for (let k in fields) {
                if (!fields.hasOwnProperty(k)) continue;
                if (fields[k].type !== "markdown" || (fields[k].hasOwnProperty("mode") && fields[k].mode !== "editormd")) continue;
                let fieldObj = that.fields[that.id + (that.tab ? `_${that.tab}` : "") + `_${k}`];
                fieldObj.reloadEditormd();
            }
        }

        // 数据提交
        submit() {
            let that = this;
            let [formData, formTabData] = yunj.formData(that.id, validate);
            if (yunj.isEmptyObj(formData) || yunj.isEmptyObj(formTabData)) return false;
            let requestData = {
                builderId: that.id,
                builderAsyncType: 'submit',
                data: JSON.stringify(formData),
                tabData: JSON.stringify(formTabData)
            };

            yunj.request(that.url, requestData, "post").then(res => {
                // 来源页面
                if (yunj.isObj(res.data) && res.data.hasOwnProperty('reload') && res.data.reload) {
                    if (that.rawTable) {
                        that.rawTable.render();
                    } else if (that.rawPageWin) {
                        that.rawPageWin.location.reload(true);
                    }
                }
                // 关闭弹出层
                if (that.isPopup) yunj.closeCurr();
            }).catch(e => {
                yunj.error("表单提交失败");
            });

        }

        // 设置事件绑定
        setEventBind() {
            let that = this;

            // 窗口大小发生变化时触发
            $(win).resize(function () {
                that.renderButton();
            });

            // 监听tab切换
            if (that.tabTitleEl) {
                element.on(`tab(${that.id}_tab)`, function (data) {
                    that.tabChange();
                });
            }

            // 监听return点击
            that.boxEl.on('click', '.yunj-btn-return', function () {
                yunj.closeCurr();
            });

            // 监听reload点击
            that.boxEl.on('click', '.yunj-btn-reload', function () {
                location.reload(true);
            });

            // 监听reset点击
            that.boxEl.on('click', '.yunj-btn-reset', function () {
                $(doc).trigger(`yunj_form_${that.id}_reset`);
            });

            // 监听clear点击
            that.boxEl.on('click', '.yunj-btn-clear', function () {
                $(doc).trigger(`yunj_form_${that.id}_clear`);
            });

            // 监听submit点击
            that.boxEl.on('click', '.yunj-btn-submit', function () {
                that.submit();
            });
        }

    }

    $(doc).ready(function () {
        win.yunj.form = {};

        let formEls = $('form[type=yunj]');
        if (yunj.isUndefined(YUNJ_FORM) || !yunj.isObj(YUNJ_FORM) || formEls.length <= 0) return;
        formEls.each(function () {
            let id = $(this).attr('id');
            if (!YUNJ_FORM.hasOwnProperty(id)) return true;
            let args = YUNJ_FORM[id];
            win.yunj.form[id] = new YunjForm({
                id: id,
                elem: $(this),
                args: args
            });
        });
    });

});